//
// Unihan Input Method
//
// Copyright © 2002-2007 Sun Wah Linux Ltd.
//
//
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2.1 of the
// License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
// USA
//
// $Id: socket_gnome2.c 757 2007-05-10 08:19:31Z roger $
//

/*
** $Id: socket_gnome2.c 757 2007-05-10 08:19:31Z roger $
**
** SWin X Auxilliary Objects
** External module -- IM status panel-applet for GNOME Panel 2
*/

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <panel-applet.h>
#include <X11/Xlib.h>

/* Define applet info */
#define APPLET_PKG "unihan_socket_applet"
#define APPLET_VER VERSION

#define GNOMELOCALEDIR LOCALEDIR

static void socket_destroyed(GtkObject *, gpointer);
static gint ignore_1st_click(GtkWidget *, GdkEvent *, gpointer);
static gboolean plug_removed(GtkSocket *, gpointer);
static gboolean get_plug_id(void);

static GtkWidget *plug_socket = NULL;
static GtkWidget *handle = NULL;
static gboolean is_plugged = FALSE;
static guint32 plug_id = 0;
static GtkClipboard *clip = NULL;
static GtkWidget *box = NULL;

static gboolean isRunning = FALSE;

static GtkWidget *
create_socket(void)
{
	GtkWidget *new_socket = gtk_socket_new();
	g_signal_connect(G_OBJECT(new_socket), "destroy",
			G_CALLBACK(socket_destroyed), NULL);
	g_signal_connect(G_OBJECT(new_socket), "plug-removed",
			G_CALLBACK(plug_removed), NULL);
	gtk_widget_set_events(new_socket, GDK_BUTTON_PRESS_MASK);
	gtk_widget_show_all(new_socket);
	return new_socket;
}

/* 'inspired' by tasklist.c in gnome-core! */
static gint
ignore_1st_click(GtkWidget *w, GdkEvent *e, gpointer data)
{
	GdkEventButton *be = (GdkEventButton *)e;

	if ((e->type == GDK_BUTTON_PRESS || e->type == GDK_BUTTON_RELEASE)
	    && be->button == 1 && be->window != plug_socket->window)
		be->button = 2;
	
	return FALSE;
}

static void
socket_destroyed(GtkObject *o, gpointer data)
{
	is_plugged = FALSE;
	plug_socket = create_socket();
	gtk_container_add(GTK_CONTAINER(box), plug_socket);
}

static gboolean
plug_removed(GtkSocket *s, gpointer data)
{
	is_plugged = FALSE;
	return FALSE;
}

static gint
check_is_plugged(gpointer data)
{
	if (!is_plugged) {
		get_plug_id();
	} else {
		// check if window still exists
		XWindowAttributes foo;

		gdk_error_trap_push();
		XGetWindowAttributes(GDK_DISPLAY(), plug_id, &foo);
		if (gdk_error_trap_pop() != 0) {
			is_plugged = FALSE;
			g_warning("status window lost");
		}
	}
	
	return TRUE;
}

#define UNIHAN_STATUS_HIDE_ICON		1
#define UNIHAN_STATUS_ABOUT_ITEM	2
#define UNIHAN_STATUS_PREFERENCES_ITEM	3

static void
send_to_plug(long msg)
{
	GdkEventClient e;

	if (plug_id == 0)
		return;

	e.type = GDK_CLIENT_EVENT;
	e.window = GTK_WIDGET(plug_socket)->window;
	e.send_event = TRUE;
	e.message_type = gdk_atom_intern("_UNIHAN_STATUS_UI_CONTROL", FALSE);
	e.data_format = 32;
	e.data.l[0] = msg;
	e.data.l[1] = e.data.l[2] = e.data.l[3] = e.data.l[4] = 0;
	gdk_error_trap_push();
	gdk_event_send_client_message((GdkEvent *)&e, plug_id);
	gdk_error_trap_pop();
}

static gboolean
get_plug_id(void)
{
	GtkSelectionData *d;
	guint32 new_plug_id;
	XWindowAttributes foo;

	d = gtk_clipboard_wait_for_contents(clip, 
			gdk_atom_intern("_PLUG_ID", FALSE));
	if (!d) return FALSE;
	if (!d->data) return FALSE;
	
	new_plug_id = *(guint32*)d->data;

	gtk_selection_data_free(d);

	// Check if window still exists
	gdk_error_trap_push();
	XGetWindowAttributes(GDK_DISPLAY(), new_plug_id, &foo);
        if (gdk_error_trap_pop() != 0)
		return FALSE;

        plug_id = new_plug_id;
        gtk_socket_add_id(GTK_SOCKET(plug_socket), (GdkNativeWindow)plug_id);
        is_plugged = TRUE;

	send_to_plug(UNIHAN_STATUS_HIDE_ICON);
	return TRUE;
}

static GtkWidget *
create_unihan_icon(void)
{
	GtkWidget *w = gtk_event_box_new();
	GtkWidget *icon = gtk_image_new_from_file(UNIHAN_DATA_DIR "/images/icon.png");
	g_signal_connect(G_OBJECT(w), "event",
			G_CALLBACK(ignore_1st_click), NULL);
	gtk_container_add(GTK_CONTAINER(w), icon);
	return w;
}

static void
preferences_item_handler(BonoboUIComponent *comp, gpointer data, const char *c)
{
	send_to_plug(UNIHAN_STATUS_PREFERENCES_ITEM);
}

static void
about_item_handler(BonoboUIComponent *comp, gpointer data, const char *c)
{
	send_to_plug(UNIHAN_STATUS_ABOUT_ITEM);
}

static const BonoboUIVerb menuVerbList[] = {
	BONOBO_UI_VERB("UnihanPreferences", preferences_item_handler),
	BONOBO_UI_VERB("UnihanAbout", about_item_handler),
	BONOBO_UI_VERB_END
};

static void
socket_applet_new(PanelApplet *applet)
{
	box = gtk_hbox_new(FALSE, 0);
	
	plug_socket = create_socket();

	//handle = gtk_handle_box_new();
	//gtk_signal_connect(GTK_OBJECT(handle), "event",
	//		   GTK_SIGNAL_FUNC(ignore_1st_click), NULL);
	//gtk_container_add(GTK_CONTAINER(handle), plug_socket);
	//gtk_widget_show_all(handle);
	handle = create_unihan_icon();
	gtk_box_pack_start(GTK_BOX(box), handle, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(box), plug_socket, FALSE, FALSE, 0);

	panel_applet_setup_menu_from_file(applet,
			UNIHAN_DATA_DIR,
			"socket_gnome2_menu.xml",
			"unihan_socket",
			menuVerbList,
			NULL);

	gtk_container_add(GTK_CONTAINER(applet), box);
	gtk_widget_show_all(GTK_WIDGET(applet));

	clip = gtk_clipboard_get(gdk_atom_intern("_UNIHAN_STATUS", FALSE));
	get_plug_id();

	// check every 5 seconds
	gtk_timeout_add(5000, check_is_plugged, NULL);

	return;
}

static gboolean
socket_applet_factory(PanelApplet *applet,
		      const gchar *iid,
		      gpointer     data)
{
//	GtkWidget *d;
	
	if (!isRunning) {
//		isRunning = TRUE;
		socket_applet_new(applet);
	}
#if 0
	d = gtk_message_dialog_new(NULL,
				   GTK_DIALOG_DESTROY_WITH_PARENT,
				   GTK_MESSAGE_ERROR, 
				   GTK_BUTTONS_CLOSE,
				   _("You may only have one Unihan Status Applet on the desktop at a time."));
	gtk_dialog_run(GTK_DIALOG(d));
	gtk_widget_destroy(d);
	gtk_widget_destroy(GTK_WIDGET(applet));
#endif
	return TRUE;
}

PANEL_APPLET_BONOBO_FACTORY("OAFIID:Com_SW-Linux_Unihan_SocketApplet_Factory",
		            PANEL_TYPE_APPLET,
		            APPLET_PKG,
			    APPLET_VER,
			    socket_applet_factory,
			    NULL);
#if 0
int main (int argc, char *argv [])                                              
{       
        bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);                       
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");                     
        textdomain (GETTEXT_PACKAGE);                                           
        gnome_program_init (PPLET_PKG, APPLET_VER,                         
                            LIBGNOMEUI_MODULE,                                  
                            argc, argv,                                         
                            GNOME_PARAM_NONE);
	
        return panel_applet_factory_main("OAFIID:Unihan_SocketApplet_Factory", PANEL_TYPE_APPLET, socket_applet_factory, NULL);           
}
#endif

// vi:ts=4:nowrap:cin:expandtab
